package com.lagou.service;

import com.SpringUtils;
import com.lagou.handler.UserServiceHandler;
import com.lagou.request.RpcDecoder;
import com.lagou.request.RpcEncoder;
import com.lagou.request.RpcRequest;
import com.lagou.serializer.JSONSerializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Service
public class UserServiceImpl implements IUserService, InitializingBean {

    private final JSONSerializer jsonSerializer = new JSONSerializer();

    //将来客户单要远程调用的方法
    public RpcRequest sayHello(RpcRequest req) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        Object bean = SpringUtils.getBean(req.getClassName());
        Method declaredMethod = bean.getClass().getDeclaredMethod(req.getMethodName(), req.getParameterTypes());
        declaredMethod.setAccessible(true);
        declaredMethod.invoke(bean, req.getParameters());

        RpcRequest request = new RpcRequest();
        request.setClassName("");
        request.setMethodName("");
        request.setParameters(new String[]{"success"});
        request.setParameterTypes(new Class[]{String.class});
        request.setRequestId(req.getRequestId());
        return request;
    }

    public void calldemo(String str){
        System.out.println(str);
    }

    //创建一个方法启动服务器
    public void startServer() throws InterruptedException {
        //1.创建两个线程池对象
        NioEventLoopGroup  bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup  workGroup = new NioEventLoopGroup();

        //2.创建服务端的启动引导对象
        ServerBootstrap serverBootstrap = new ServerBootstrap();

        //3.配置启动引导对象
        serverBootstrap.group(bossGroup,workGroup)
                //设置通道为NIO
                .channel(NioServerSocketChannel.class)
                //创建监听channel
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        //获取管道对象
                        ChannelPipeline pipeline = nioSocketChannel.pipeline();
                        //给管道对象pipeLine 设置编码
                        pipeline.addLast(new RpcEncoder(RpcRequest.class, jsonSerializer));
                        pipeline.addLast(new RpcDecoder(RpcRequest.class, jsonSerializer));
                        //把我们自顶一个ChannelHander添加到通道中
                        pipeline.addLast(new UserServiceHandler());
                    }
                });

        //4.绑定端口
        serverBootstrap.bind(8999).sync();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        startServer();
    }

}
